home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
17 Bit Software 6: Level 6
/
17 Bit - Level 6 (1998)(Epic Marketing)[!].iso
/
!applications!
/
st2amiga
/
st2amiga.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-07
|
8KB
|
241 lines
#include <stdio.h>
/* SET TABS TO 4 !!!! */
/* ST2Amiga Format-convert ST Executables to Amiga Executables.
*
* (C) Copyright, Dave Campbell 90/91
*
* This software is freely distributable. Modified versions may be
* redistributed provided that the modifications made are fully
* documented as such.
*
* Its purpose is to aid the binary conversion of ST executables into
* Amiga executables using the ReSource disassembler. To do this
* you'll need some good books such as "Advanced MSDOS Programming" by
* Ray Duncan, and other books on GEM (books on PC-GEM are best).
* The ST's system call TRAPs map directly to PC and GEM calls. Eg
* TRAP #1 is INT 21h.
*
* Don't forget to send me whatever you've converted (PD only)!!
*
* Many ST programs use very large BSS sections making them particularly
* memory-hungry. The ST's memory allocation scheme is totally stuffed
* and so many programs do their own memory allocation from their huge
* BSS section. The people who designed the ST's OS certainly made
* many more mistakes than Commodore did with the Amiga.
*
* There is a program called Dos-2-Dos which provides copying of files
* to/from ST format disks.
* Older ST disks are the same format as MSDOS 720k 3.5 inch, but the
* bootblock and possibly a few other small things are slightly different.
* All newer standard ST formatted disks will be identical to MSDOS
* formatted disks.
*
* The ST does not support scatter-loading. All sections must be
* consecutive; CODE, DATA, BSS. For this reason I merge the code
* and data sections, and besides, it makes the job easy for me.
* BSS comes out as a separate hunk -> its your responsibility to fix
* up the dependencies.
*
* Why don't I space my source out more? I feel sorry for my space bar.
*
* Contact address:
*
* David Campbell
* 36 Hemsworth Street
* Acacia Ridge QLD 4110
* AUSTRALIA
*
* email: dave@csis.dit.csiro.au
*
* If you haven't heard of ReSource, its the ultimate disassembler.
* For ReSource contact:
*
* In OZ: Glen McDiarmid In the US: The Puzzle Factory
* 28 Marginson Street PO Box 986
* Ipswich QLD 4305 Veneta OR 97487
* AUSTRALIA USA
*
* (07) 812-2963 (503) 935 3709
*/
struct st_header {
unsigned short branch;
unsigned long code_size;
unsigned long data_size;
unsigned long bss_size;
unsigned long sym_size;
unsigned long xx;
unsigned long flag0;
unsigned short xxxx;
};
struct symbol {
unsigned long sym_name;
unsigned long sym_name2; /* 8 character symbols */
unsigned short flags;
unsigned long offset;
};
main(argc,argv)
int argc;
char **argv;
{
struct st_header ah;
unsigned long codedata_size,bss_size; /* in longwords, not bytes */
unsigned long first_long,count;
unsigned char b;
long apos;
int r;
unsigned long l,num_hunks;
FILE *inf,*outf;
char *mem;
if(argc!=3) {
usage:
printf( "\2335;33mST2Amiga\2330;31m 1.1"
" Format-convert executables from ST -> Amiga.\n"
" For use with the ReSource disassembler.\n"
" by Dave Campbell (dave@csis.dit.csiro.au)."
"\n\n\2335;33mUSAGE: ST2Amiga <ST-Exe> <Amiga-Exe>"
"\2330;31m\n\n");
exit(0);
}
inf=fopen(argv[1],"r");
if(!inf) {
printf("Error reading file %s.\n",argv[1]);
exit(0);
}
outf=fopen(argv[2],"w");
if(!outf) {
printf("Error writing file %s.\n",argv[2]);
exit(0);
}
r=fread((char *)&ah,1,sizeof(ah),inf);
if(r!=sizeof(ah)) {
inv_atari_exe:
printf("Invalid atari executable %s.\n",argv[1]);
exit(0);
}
if(ah.branch!=0x601a)
goto inv_atari_exe; /* anti-goto people go jump */
printf("Code size: $%lx\n",ah.code_size);
printf("Data size: $%lx\n",ah.data_size);
printf("Bss size: $%lx\n",ah.bss_size);
if(!(ah.flag0&1))
printf("Warning: This Atari executable assumes a cleared heap.\n");
codedata_size=(ah.code_size+ah.data_size+3)>>2; /* up to next longword */
bss_size=(ah.bss_size+3)>>2;
l=0x03f3; fwrite((char *)&l,sizeof(long),1,outf); /* hunk_header */
l=0x0000; fwrite((char *)&l,sizeof(long),1,outf); /* end of name list */
num_hunks=0;
if(codedata_size) ++num_hunks;
if(bss_size) ++num_hunks;
fwrite((char *)&num_hunks,sizeof(long),1,outf); /* table size */
l=0x0000; fwrite((char *)&l,sizeof(long),1,outf); /* first hunk */
--num_hunks;
fwrite((char *)&num_hunks,sizeof(long),1,outf); /* last hunk */
++num_hunks;
if(codedata_size) /* size of each hunk */
fwrite((char *)&codedata_size,sizeof(long),1,outf);
if(bss_size)
fwrite((char *)&bss_size,sizeof(long),1,outf);
if(codedata_size) {
l=0x03e9; fwrite((char *)&l,sizeof(long),1,outf); /* hunk_code */
fwrite((char *)&codedata_size,sizeof(long),1,outf);
mem=(char *)malloc(codedata_size<<2);
if(!mem) {
printf("Cannot allocate %d bytes of memory.\n",codedata_size<<2);
exit(0);
}
r=fread(mem,1,ah.code_size+ah.data_size,inf);
if(r!=ah.code_size+ah.data_size) {
free(mem);
goto inv_atari_exe;
}
fwrite(mem,1,codedata_size<<2,outf);
free(mem);
}
if(ah.sym_size) { /* symbols are present */
struct symbol sym;
int hunk_written=0;
count=ah.sym_size/sizeof(sym);
while(count) {
r=fread((char *)&sym,1,sizeof(sym),inf);
if(r!=sizeof(sym))
goto inv_atari_exe;
if(!(sym.flags&0x4000)) {
if(!hunk_written) {
l=0x03f0; fwrite((char *)&l,sizeof(long),1,outf);
/* hunk_symbol */
hunk_written=1; /* never again */
}
l=0x0002; fwrite((char *)&l,sizeof(long),1,outf);
/* length of symbols in longs */
/* printf("%04x %s\n",sym.flags,
(sym.flags=0,(char *)&sym.sym_name)); */
fwrite((char *)&sym.sym_name,1,8,outf);
fwrite((char *)&sym.offset,sizeof(long),1,outf);
}
count--;
}
l=0x0000; fwrite((char *)&l,sizeof(long),1,outf); /* terminator */
}
r=fread((char *)&first_long,1,sizeof(long),inf); /* read first reloc long */
if(r!=sizeof(long))
goto inv_atari_exe;
if(first_long) {
count=1;
l=0x03ec; fwrite((char *)&l,sizeof(long),1,outf); /* hunk_reloc32 */
apos=ftell(inf);
r=fread((char *)&b,1,1,inf); /* first pass to count */
if(r!=1)
goto inv_atari_exe;
while(b) {
if(b>=2 && b<255) /* only count the relocs */
++count;
fread((char *)&b,1,1,inf);
}
fwrite((char *)&count,1,sizeof(long),outf);
l=0; fwrite((char *)&l,sizeof(long),1,outf); /* reloc on hunk 0 */
fwrite((char *)&first_long,1,sizeof(long),outf);
fseek(inf,apos,0); /* back to where we were */
r=fread((char *)&b,1,1,inf);
if(r!=1)
goto inv_atari_exe;
/* ST relocation scheme */
while(b) { /* 0 -> end of relocation */
if(b==1)
first_long+=254; /* 1 -> skip 254 bytes */
else if(b&1)
goto inv_atari_exe; /* other odds undefined */
else { /* other evens skip bytes and relocate */
first_long+=b;
fwrite((char *)&first_long,sizeof(long),1,outf);
}
r=fread((char *)&b,1,1,inf);
if(r!=1)
goto inv_atari_exe;
}
l=0x0000; fwrite((char *)&l,sizeof(long),1,outf); /* end of reloc */
l=0x03f2; fwrite((char *)&l,sizeof(long),1,outf); /* hunk_end */
}
if(bss_size) {
l=0x03eb; fwrite((char *)&l,sizeof(long),1,outf); /* hunk_bss */
fwrite((char *)&bss_size,sizeof(long),1,outf);
fseek(inf,ah.bss_size,1);
}
l=0x03f2; fwrite((char *)&l,sizeof(long),1,outf); /* hunk_end */
/* CLOSE UP SHOP */
fclose(inf);
fclose(outf);
}